home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog 125
/
Freelog_MarsAvril2015_No125.iso
/
Musique
/
Quod Libet
/
quodlibet-3.3.0-installer.exe
/
bin
/
quodlibet
/
qltk
/
entry.pyc
(
.txt
)
< prev
next >
Wrap
Python Compiled Bytecode
|
2014-12-31
|
11KB
|
281 lines
# Source Generated with Decompyle++
# File: in.pyc (Python 2.7)
import math
from gi.repository import Gtk, GObject, Gdk, Gio, Pango
from quodlibet.qltk import is_accel, add_fake_accel
from quodlibet.qltk.x import SeparatorMenuItem
class EditableUndo(object):
'''A simple undo/redo implementation for gtk widgets that
support the gtk.Editable interface'''
def set_undo(self, val):
if val:
self._EditableUndo__enable_undo()
else:
self._EditableUndo__disable_undo()
def reset_undo(self):
self._EditableUndo__history = []
self._EditableUndo__re_history = []
self._EditableUndo__in_pos = -1
self._EditableUndo__del_pos = -1
self._EditableUndo__last_space = False
def undo(self):
self._EditableUndo__do(self._EditableUndo__history, self._EditableUndo__re_history)
def redo(self):
self._EditableUndo__do(self._EditableUndo__re_history, self._EditableUndo__history)
def can_undo(self):
return self._EditableUndo__can_do(self._EditableUndo__history)
def can_redo(self):
return self._EditableUndo__can_do(self._EditableUndo__re_history)
def __enable_undo(self):
self.reset_undo()
self._EditableUndo__handlers = [
self.connect('insert-text', self._EditableUndo__insert_before),
self.connect('delete-text', self._EditableUndo__delete_before),
self.connect('populate-popup', self._EditableUndo__popup),
self.connect('key-press-event', self._EditableUndo__key_press)]
def __key_press(self, entry, event):
if is_accel(event, '<ctrl>z'):
self.undo()
return True
if None(event, '<ctrl><shift>z'):
self.redo()
return True
def __disable_undo(self):
for handler in self._EditableUndo__handlers:
self.disconnect(handler)
del self._EditableUndo__history
del self._EditableUndo__re_history
del self._EditableUndo__last_space
del self._EditableUndo__in_pos
del self._EditableUndo__del_pos
def __popup(self, entry, menu):
undo = Gtk.ImageMenuItem(Gtk.STOCK_UNDO, use_stock = True)
add_fake_accel(undo, '<ctrl>z')
redo = Gtk.ImageMenuItem(Gtk.STOCK_REDO, use_stock = True)
add_fake_accel(redo, '<ctrl><shift>z')
sep = SeparatorMenuItem()
for widget in [
sep,
redo,
undo]:
widget.show()
undo.connect(('activate',), (lambda : self.undo()))
redo.connect(('activate',), (lambda : self.redo()))
undo.set_sensitive(self.can_undo())
redo.set_sensitive(self.can_redo())
for item in [
sep,
redo,
undo]:
menu.prepend(item)
def __all(self):
text = self.get_chars(0, -1).decode('utf-8')
pos = self.get_position()
return [
text,
pos]
def __add(self):
self._EditableUndo__history.append(self._EditableUndo__all())
self._EditableUndo__re_history = []
def __insert_before(self, entry, text, length, position):
self._EditableUndo__del_pos = -1
pos = self.get_position()
if not pos != self._EditableUndo__in_pos:
if self._EditableUndo__last_space or text != ' ' or length > 1:
self._EditableUndo__add()
self._EditableUndo__last_space = text == ' '
self._EditableUndo__in_pos = pos + 1
return None
def __delete_before(self, entry, start, end):
self._EditableUndo__in_pos = -1
text = self.get_chars(start, end)
length = end - start
pos = self.get_position()
if not pos != self._EditableUndo__del_pos:
if self._EditableUndo__last_space or text != ' ' or length > 1:
self._EditableUndo__add()
self._EditableUndo__last_space = text == ' '
self._EditableUndo__del_pos = end - 1
return None
def __inhibit(self):
for handler in self._EditableUndo__handlers:
self.handler_block(handler)
def __uninhibit(self):
for handler in self._EditableUndo__handlers:
self.handler_unblock(handler)
def __can_do(self, source):
return bool(source)
def __do(self, source, target):
if not self._EditableUndo__can_do(source):
return None
self._EditableUndo__del_pos = None
self._EditableUndo__in_pos = None
self._EditableUndo__inhibit()
now = self._EditableUndo__all()
last = source.pop(-1)
if now != last:
target.append(now)
(text, pos) = last
self.delete_text(0, -1)
self.insert_text(text, 0)
self.set_position(pos)
self._EditableUndo__uninhibit()
class Entry(Gtk.Entry):
def __init__(self, *args, **kwargs):
super(Entry, self).__init__(*args, **kwargs)
self._max_width_chars = -1
self.set_width_chars(5)
def set_max_width_chars(self, value):
'''Works with GTK+ <3.12'''
self._max_width_chars = value
self.queue_resize()
def do_get_preferred_width(self):
(minimum, natural) = Gtk.Entry.do_get_preferred_width(self)
if self._max_width_chars >= 0:
style_context = self.get_style_context()
border = style_context.get_border(Gtk.StateFlags.NORMAL)
padding = style_context.get_padding(Gtk.StateFlags.NORMAL)
pango_context = self.get_pango_context()
metrics = pango_context.get_metrics(pango_context.get_font_description(), pango_context.get_language())
char_width = metrics.get_approximate_char_width()
digit_width = metrics.get_approximate_digit_width()
char_pixels = int(math.ceil(float(max(char_width, digit_width)) / Pango.SCALE))
space = border.left + border.right + padding.left + padding.right
nat_width = self._max_width_chars * char_pixels + space
natural = max(nat_width, minimum)
return (minimum, natural)
class UndoEntry(Entry, EditableUndo):
def __init__(self, *args):
super(UndoEntry, self).__init__(*args)
self.set_undo(True)
def set_text(self, *args):
super(UndoEntry, self).set_text(*args)
self.reset_undo()
class ClearEntryMixin(object):
'''A clear icon mixin supporting newer Gtk.Entry or
a separate clear button as a fallback.
'''
__gsignals__ = {
'clear': (GObject.SignalFlags.RUN_LAST | GObject.SignalFlags.ACTION, None, ()) }
def enable_clear_button(self):
'''Enables the clear icon in the entry'''
gicon = Gio.ThemedIcon.new_from_names([
'edit-clear-symbolic',
'edit-clear'])
self.set_icon_from_gicon(Gtk.EntryIconPosition.SECONDARY, gicon)
self.connect('icon-release', self._ClearEntryMixin__clear)
def __clear(self, button, *args):
self.delete_text(0, -1)
self.emit('clear')
class ClearEntry(UndoEntry, ClearEntryMixin):
__gsignals__ = ClearEntryMixin.__gsignals__
class ValidatingEntryMixin(object):
'''An entry with visual feedback as to whether it is valid or not.
The given validator function gets a string and returns True (green),
False (red), or None (black).
parse.Query.is_valid_color mimicks the behavior of the search bar.
If the "Color search terms" option is off, the entry will not
change color.'''
INVALID = Gdk.RGBA(0.8, 0, 0)
VALID = Gdk.RGBA(0.3, 0.6, 0.023)
def set_validate(self, validator = None):
if validator:
self.connect('changed', self._ValidatingEntryMixin__color, validator)
def __color(self, widget, validator):
value = validator(self.get_text().decode('utf-8'))
if value is True:
color = self.VALID
elif value is False:
color = self.INVALID
elif value and isinstance(value, basestring):
color = Gdk.RGBA()
color.parse(value)
else:
color = None
if color and self.get_property('sensitive'):
self.override_color(Gtk.StateType.NORMAL, color)
else:
self.override_color(Gtk.StateType.NORMAL, None)
class ValidatingEntry(ClearEntry, ValidatingEntryMixin):
def __init__(self, validator = None, *args):
super(ValidatingEntry, self).__init__(*args)
self.set_validate(validator)